package com.dsfa.filter;

import cn.hutool.core.util.XmlUtil;
import com.dsfa.biz.dataCenter.DataCenterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;

import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;
import javax.xml.ws.handler.MessageContext;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;


/**
 * @Description: TODO
 * @ClassName: WsUserInInterceptor
 * @Author: wangdm
 * @Date: 2024/1/22
 */
@Slf4j
public class WsOutInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
    //private BusService busServer;
    private DataCenterService dataCenterService;

    public WsOutInterceptor() {
        // 协议前进行拦截
        super(Phase.PRE_STREAM);
        //super(Phase.WRITE);
        this.dataCenterService = new DataCenterService();
    }

    public WsOutInterceptor(DataCenterService dataCenterService) {
        // 协议前进行拦截
        super(Phase.PRE_STREAM);
        //super(Phase.WRITE);
        this.dataCenterService = dataCenterService;
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        String logPre = "[WsOutInterceptor] ws代理 ";
        String output = "";
        String remark = "";
        String logId = "";
        String timeStr = "";
        try {
            Header hId = message.getHeader(new QName("logId"));
            logId = ((Element) hId.getObject()).getTextContent();
            if (StringUtils.isNotEmpty(logId)) {
                Header hTime = message.getHeader(new QName("timeStart"));
                timeStr = ((Element) hTime.getObject()).getTextContent();
            }
            // 从流中获取返回内容
            OutputStream os = message.getContent(OutputStream.class);
            CachedOutputStream cs = new CachedOutputStream();
            message.setContent(OutputStream.class, cs);
            message.getInterceptorChain().doIntercept(message);
            CachedOutputStream cachedOutputStream = (CachedOutputStream) message.getContent(OutputStream.class);
            InputStream in = cachedOutputStream.getInputStream();
            output = IOUtils.toString(in, "UTF-8");
            // 修改内容为集成平台要求的格式
            log.info("{}修改内容为集成平台要求的格式", logPre);
            int start = output.indexOf("<soap:Header>");
            int end = output.indexOf("</soap:Header>");
            if (start > 0 && end > start) {
                output = output.substring(0, start) + output.substring(end + 14);
                /*output = output.substring(start + 8, end);
                output = StringEscapeUtils.unescapeXml(output);*/
                try {
                    output = XmlUtil.format(output);
                } catch (Exception e) {
                    log.error("{}结果数据解析异常：{}，仍然返回：{}", logPre, e.getMessage(), output);
                    e.printStackTrace();
                    // throw new Fault(new IllegalArgumentException(e.getMessage()));
                }
            }
            // 处理完后写回流中
            IOUtils.copy(new ByteArrayInputStream(output.getBytes()), os);
            cs.close();
            os.flush();
            message.setContent(OutputStream.class, os);
            log.info("{}处理完后写回流中", logPre);
        } catch (Exception e) {
            log.error("{}解析异常：{}", logPre, e.getMessage());
            remark = e.getMessage();
            throw new Fault(new IllegalArgumentException(String.format("解析报文异常: %s", e.getMessage())));
        } finally {
            //更新输出结果到日志记录中
            //List<Header> headers = message.getHeaders();
            //Header hId = message.getHeader(new QName("logId"));
            //String logId = ((Element) hId.getObject()).getTextContent();
            if (StringUtils.isNotEmpty(logId)) {
                //Header hTime = message.getHeader(new QName("timeStart"));
                //String timeStr = ((Element) hTime.getObject()).getTextContent();
                dataCenterService.setAgentWSLogResponse(logId,
                        (int) ((System.currentTimeMillis() - Long.parseLong(timeStr)) / 1000), output, remark
                        , ((HttpServletResponse) message.get("HTTP.RESPONSE")).getStatus());
                log.info("{}更新输出结果到日志记录中,logId:{},timeStr:{}", logPre, logId, timeStr);
            }
        }
    }

}
